
// import * as d3 from "../lib/d3.js";
import * as d3 from "d3";

/**
 * @param {Element} node
 * @returns {boolean} true if the element does not have <i>aria-disabled=true</i>
 */
export function isEnabled(node) {
    return !!node && node.getAttribute("aria-disabled") !== "true";
}

/*
function isVisible() {
    return this.offsetWidth > 0 || this.offsetHeight > 0 || this.getClientRects().length > 0;
}
*/

/**
 * @param {Element} element
 * @returns {boolean} true if the element is inert or has an inert ancestor.
 */
export function isInert(element) {
    for (let cursor = element ?? null; cursor !== null; cursor = (cursor.parentElement ?? null)) {
        if (cursor.hasAttribute("inert")) {
            return true;
        }
    }
    return false;
}

/**
 * @param {Function} callback
 * @returns {Function} a function that invokes <i>callback</i> with the <i>this</i> context passed as the first argument
 */
export function hoist(callback) {
    return function() {
        return callback(this, ...arguments);
    };
}

/**
 * @param {Function} callback
 * @returns {Function} a function that invokes <i>callback</i> with the <i>this</i> context wrapped as a D3 selection
 *          and passed as the first argument
 */
export function lift(callback) {
    return function() {
        return callback(d3.select(this), ...arguments);
    };
}

/**
 * @param {Function} callback
 * @returns {Function} a function that invokes <i>callback</i> only when the <i>this</i> context is a DOM element that
 *          is enabled (defined as not having <i>aria-disabled=true</i>)
 */
export function whenEnabled(callback) {
    return function() {
        if (isEnabled(this)) {
            return callback.apply(this, arguments);
        }
    };
}

/**
 * @param {Element} element
 * @returns {string} selector for elements referenced in aria-controls, e.g., aria-controls="b  c a "  -->  "#a,#b,#c"
 */
export function ariaControls(element) {
    // aria-controls is a space-delimited set of element ids
    const ids = element.getAttribute("aria-controls") ?? "";
    return ids.split(/\s+/).filter(e => e !== "").map(e => "#" + e).sort().join(",");
}

/**
 * stops propagation and prevents default on the specified event
 * @param {Event} event
 */
export function squash(event) {
    event.stopPropagation();
    event.preventDefault();
}
